<?php
namespace app\api\controller;
/**
 * 子系统访问权限控制器(app\api\controller)
 * 用于验证账户信息 登入信息 获取权限信息等
 */
use think\Controller;
use think\Db;
use think\Cache;
use app\api\model\ApiAuthorizationModel;
use app\admin\model\AdminMenuModel;
use app\admin\model\AccessModel;
use app\admin\model\ModuleMenuModel;
use app\api\model\ApiAccessAuthorityModel;
/**
 * 子系统访问权限控制器
 *
 *错误码:
 *
 * 10001    appid 不存在或为空
 * 10002    appsecret 不存在或为空
 * 10003    appsecret appid 值错误,信息校验失败
 *
 * 
 */
class ApiAccessAuthorityController extends Controller
{

    /**
     * 1、获取token access_token
     * @param appid 第三方应用唯一凭证
     * @param appsecret 第三方应用唯一凭证密钥，即appsecret
     * @return [type] [description]
     */
    public function accessToken(){
        $data = $this->request->get();

        if( !isset( $data [ 'appid' ] ) || empty( $data [ 'appid' ] )  ){
            return zy_json_echo( false, '参数缺失' ,null , 10001 );
        } 
        if( !isset( $data [ 'appsecret' ] ) || empty( $data [ 'appsecret' ] )  ){
            return zy_json_echo( false, '参数缺失' , null , 10002 );
        }
        $accessAuthority = new ApiAccessAuthorityModel();
        $res = $accessAuthority->accountPermission( $data [ 'appid' ] , $data [ 'appsecret' ]  );

        if( false === $res ){
            return zy_json_echo( false , '授权信息错误' , null , 10003 );
        }
        
        
        $Jwt = new \sign\Jwt( $res ['key'] );
        //获取token
        $arr = [
            'appid' => $data [ 'appid' ] ,
            'appsecret' => $data [ 'appsecret' ] ,
        ];
        $accessToken = $Jwt->accessToken($arr);
        if( $accessToken == false ){
            return zy_json_echo( false , '传入格式错误' , '' , 10004 );
        }
        return zy_json_echo(true,'成功！',array('access_token'=>$accessToken),200);
    }

    /**
     * 2、获取jwt token
     * @param appid 第三方应用唯一凭证
     * @param appsecret 第三方应用唯一凭证密钥，即appsecret
     * @return [type] [description]
     */
    public function getToken()
    {
        //dump( base64_encode('卓远,###8a5745e3d312f97f678853c603af8e90') );
        //5Y2T6L+cJiMjIzhhNTc0NWUzZDMxMmY5N2Y2Nzg4NTNjNjAzYWY4ZTkw
        $data=$this->request->get();

        if( !isset( $data [ 'sub' ] ) || empty( $data [ 'sub' ] )  ){
            return zy_json_echo( false, '参数缺失' , null , 10005 );
        }

        if( !isset( $data [ 'jti' ] ) || empty( $data [ 'jti' ] )  ){
            return zy_json_echo( false, '参数缺失' , null , 10006 );
        }
        $accessAuthority = new ApiAccessAuthorityModel();
		
        $sub = base64_decode( str_replace( ' ' , '+' , $data [ 'sub' ] ) );

        $sub = explode( ',' , $sub );

        $userLogin = reset($sub);
        $userPassword = end($sub);
        $res = $accessAuthority->accountPermissionByPwd( $userLogin , $userPassword );
        if( $res [ 'status' ] == false ){
            return zy_json_echo( false, $res [ 'message' ] , '' , $res [ 'code' ] );
        }

        $key = $res [ 'key' ];
        $Jwt = new \sign\Jwt( $key );

        // 验证jti 校验token
        $verifyaccessToken = $Jwt->verifyaccessToken($data['jti']);
        if($verifyaccessToken['status']=='error'){
            return zy_json_echo( false , $verifyaccessToken['message'],'', 10007 );
        }

        $data['exp']=time()+7200;
        //获取票据
        $jsapi_ticket = $Jwt->getToken($data);
        if($jsapi_ticket==false){
            return zy_json_echo(false,'传入格式错误','',10012);
        }
        return zy_json_echo(true,'成功！',$jsapi_ticket,200);

    }


     /**
     * 3、生成签名
     * @param appid 第三方应用唯一凭证
     * @param appsecret 第三方应用唯一凭证密钥，即appsecret
     * @return [type] [description]
     */
    public function signDe($data , $isApi = true )
    {
        if( !isset( $data [ 'appid' ] ) || empty( $data [ 'appid' ] )  ){
            return zy_json_echo( false, '参数缺失' ,null , 10001 );
        } 
 
        $accessAuthority = new ApiAccessAuthorityModel();
		
        $res = $accessAuthority->accountPermission( $data [ 'appid' ] , '' );

        if( false === $res ){
            return zy_json_echo( false , '授权信息错误' , null , 10003 );
        }
        
        $Generatesign = new \sign\Generatesign();
        $Jwt = new \sign\Jwt($res [ 'key' ] );


        // 验证jsapi_token
        $verifyToken=$Jwt->verifyToken($data['jsapi_ticket']);
        if($verifyToken['status']=='error'){
            return zy_json_echo(false,$verifyToken['message'],'',10014);
        }
		
        $verifyaccessToken=$Jwt->verifyaccessToken($verifyToken['data']['jti']);

        if($verifyaccessToken['status']=='error'){
            return zy_json_echo(false,$verifyaccessToken['message'],'',10015);
        }
		$appsecret = md5(md5($res['id'].$data['appid'].$res['key'].$res['create_time'])); ;
        if($verifyaccessToken['data']['appid']!=$data [ 'appid' ] || $verifyaccessToken['data']['appsecret']!=$appsecret ){
            return zy_json_echo(false,'凭证不匹配','',10016);
        }

        //验证签名
        $signV = $data['signture'];
        unset($data['signture']);
        $signature = $Generatesign->signature($data,'DECODE',$signV);
        if($signature['status']=='error'){
            return zy_json_echo(false,$signature['message'],'',10017);
        }
		if( $isApi == true ){
			return zy_json_echo(true,'成功！','',200);
		}
        return true;
    }

     /**
      * 签名验证接口
      */
    public function signVerifyTest()
    {
        $data = $this->request->param();
		
        $this->signDe( $data );
    }
	
	/**
     * [signVerifyTest description]
     * @return [type] [description]
     */
    public static function signVerify( $data , $isApi = true )
    {
        $res = (new ApiAccessAuthorityController())->signDe( $data ,$isApi );
        $result = json_decode( $res , true );
        if( $result [ 'code' ] == 200 ){
            return true;
        }
        return $res;
    }
	
	/**
     * 主系统与子系统通信协议
     */
    public static function createAgreement( $data )
    {
        $encodeStr = ( new ApiAccessAuthorityController())->assemble( $data ); 
        $randomOne = md5( rand() );
        $randomOne = substr( $randomOne , 8 , 12 );
        $encodeStr = md5 ( $encodeStr.$randomOne.$encodeStr );
        return $encodeStr;
    }

    /**
     * 组装字符串
     */
    private function assemble( $data , $str='' )
    {
        if( is_array( $data ) ){
            foreach ($data as $key => $value) {
                $str = $this->assemble( $value , $str );
            }
        }else if( is_string( $data ) ){
            $str .= $data;
        }else{
            $str .= 'jlskdhgkg';
        }
        return $str;
    }
	
	

}